package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.*;
import com.example.demo.mapper.ExamMapper;
import com.example.demo.mapper.StudentExamMapper;
import com.example.demo.service.*;
import com.example.demo.utils.AjaxJson;
import com.example.demo.utils.UserContext;
import com.example.demo.vo.examAddVo;
import com.example.demo.vo.examStudentVo;
import com.example.demo.vo.examVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 考试表 服务实现类
 * </p>
 *
 * @author
 * @since 2025-11-10
 */
@Service
public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IExamService {

    @Autowired
    IQuestionBankService questionBankService;

    @Autowired
    IExamQuestionService examQuestionService;

    @Autowired
    ICourseService courseService;

    @Autowired
    IStudentService studentService;

    @Autowired
    ICourseAllocationService courseAllocationService;

    @Autowired
//    IStudentExamService studentExamService;
    StudentExamMapper studentExamMapper;


    //TODO 大连查，做缓存......是不是应该把会变的考试状态剔除呢
    @Override
    public AjaxJson getByTeacherId(Integer teacherId) {
        List<examVo> list = this.list(new QueryWrapper<Exam>().eq("teacher_id", teacherId)).stream().map(this::buildExamVo).toList();
        return AjaxJson.getPageData((long) list.size(), list);
    }

    /**
     * TODO 也是个大连查······给单个考试做缓存
     *
     * @param examId
     * @return
     */
    @Override
    public AjaxJson getByExStId(Integer examId) {
        System.out.println(":::::::examId::::::"+examId);
        Exam exam = this.getById(examId);
        examVo examVo = buildExamVo(exam);
        // 判断是否在考试时间
        if (exam.getStartTime().isAfter(LocalDateTime.now()) || exam.getEndTime().isBefore(LocalDateTime.now())) {
            return AjaxJson.getWarning("考试时间未开始或已结束");
        }
        // 剔除答案
        examVo.getQuestionList().forEach(ex -> {
            ex.setCorrectAnswer("");
        });
        return AjaxJson.getSuccessData(examVo);
    }

    @Override
    public examVo buildExamVo(Exam exam) {
        examVo examVo = new examVo();
        examVo.setExamId(exam.getExamId());
        examVo.setExamName(exam.getExamName());
        examVo.setCourseId(exam.getCourseId());
        examVo.setCourseName(courseService.getById(exam.getCourseId()).getCourseName());
        examVo.setStartTime(exam.getStartTime());
        examVo.setEndTime(exam.getEndTime());
        examVo.setTotalScore(exam.getTotalScore());
        examVo.setExamDuration(exam.getExamDuration());
        examVo.setDescription(exam.getDescription());
        examVo.setStatus(exam.getStatus());
        //依据考试id找考试关联然后找到题目
        List<examVo.questionVo> exams = examQuestionService.list(new QueryWrapper<ExamQuestion>().eq("exam_id", exam.getExamId())).stream().map(examQuestion -> {
            examVo.questionVo questionVo = new examVo.questionVo();
            questionVo.setScore(examQuestion.getScore());
            //依据题目id获取题目
            QuestionBank questionBank = questionBankService.getById(examQuestion.getQuestionId());
            questionVo.setQuestionId(questionBank.getQuestionId());
            questionVo.setDifficulty(questionBank.getDifficulty());
            questionVo.setQuestionContent(questionBank.getQuestionContent());
            questionVo.setTypeId(questionBank.getTypeId());
            questionVo.setOptionA(questionBank.getOptionA());
            questionVo.setOptionB(questionBank.getOptionB());
            questionVo.setOptionC(questionBank.getOptionC());
            questionVo.setOptionD(questionBank.getOptionD());
            questionVo.setCorrectAnswer(questionBank.getCorrectAnswer());
            return questionVo;
        }).toList();
        examVo.setQuestionList(exams);
        return examVo;
    }


    @Override
    public AjaxJson updataByExamAddVo(examAddVo examAddVo) {
        this.remove(new QueryWrapper<Exam>().eq("exam_id", examAddVo.getExamId()));
        examQuestionService.remove(new QueryWrapper<ExamQuestion>().eq("exam_id", examAddVo.getExamId()));
        return saveExam(examAddVo);
    }

    /**
     * TODO 大连查，缓存，抽取班级获取考试方法取做缓存做缓存
     *
     * @return
     */
    @Override
    public AjaxJson getByStudentId() {
        // 从cookie获取学生
        User currentUser = UserContext.getCurrentUser();
        if (currentUser == null) return AjaxJson.getNotLogin();
        Student student = studentService.getByUserId(currentUser.getUserId());
        if (student == null) return AjaxJson.getError("学生不存在");
        System.out.println("student:::" + student);
        // 再通过班级id获取到课程，
        List<CourseAllocation> classId = courseAllocationService.list(new QueryWrapper<CourseAllocation>().eq("class_id", student.getClassId()));
        if (classId == null || classId.isEmpty()) return AjaxJson.getError("没有课程");
        System.out.println("classId:::" + classId);
        List<Course> CourseList = classId.stream().map(courseAllocation -> {
            return courseService.getById(courseAllocation.getCourseId());
        }).toList();
        if (CourseList.isEmpty()) return AjaxJson.getError("没有课程");
        System.out.println("CourseList:::" + CourseList);
        // 再依据课程找到课程的考试
        List<Exam> examList = CourseList.stream().map(course -> this.list(new QueryWrapper<Exam>().eq("course_id", course.getCourseId()))).flatMap(List::stream).toList();
        if (examList.isEmpty()) return AjaxJson.getError("没有考试");
        System.out.println("examList:::" + examList);
        Map<Integer, String> courseMap = new HashMap<>();
        for (Course course : CourseList) {
            courseMap.put(course.getCourseId(), course.getCourseName());
        }
        List<examStudentVo> examStudentVos = examList.stream().map(exam -> {
            examStudentVo examStudentVo = new examStudentVo();
            examStudentVo.setExamId(exam.getExamId());
            examStudentVo.setCourseName(courseMap.get(exam.getCourseId()));
            examStudentVo.setExamName(exam.getExamName());
            examStudentVo.setStartTime(exam.getStartTime());
            examStudentVo.setEndTime(exam.getEndTime());
            examStudentVo.setTotalScore(exam.getTotalScore());
            examStudentVo.setExamDuration(exam.getExamDuration());
            examStudentVo.setDescription(exam.getDescription());
            examStudentVo.setStatus(exam.getStatus());

            StudentExam one = studentExamMapper.selectOne(new QueryWrapper<StudentExam>().eq("student_id", student.getStudentId()).eq("exam_id", exam.getExamId()));
            if(one!=null){
                System.out.println("存在考试记录");
                if(one.getStatus()==1){
                    //已提交
                    examStudentVo.setStatus(3);
                }else if(one.getStatus()==2){
                    //超时未提交
                    examStudentVo.setStatus(4);
                }
            }

            return examStudentVo;
        }).toList();
        System.out.println("examStudentVos:::" + examStudentVos);
        // 这样就够了，具体的考试内容让前端在点击后再获取
        return AjaxJson.getPageData((long) examStudentVos.size(), examStudentVos);
    }


    private AjaxJson saveExam(examAddVo examAddVo) {
        Exam exam = new Exam();
        exam.setTeacherId(examAddVo.getTeacherId());
        exam.setCourseId(examAddVo.getCourseId());
        exam.setExamName(examAddVo.getExamName());
        exam.setStartTime(examAddVo.getStartTime());
        exam.setEndTime(examAddVo.getEndTime());
        exam.setTotalScore(examAddVo.getTotalScore());
        exam.setExamDuration(examAddVo.getExamDuration());
        exam.setDescription(examAddVo.getDescription());
        boolean save = this.save(exam);
        if (!save) {
            return AjaxJson.getError("保存失败");
        }
        List<ExamQuestion> list = examAddVo.getQuestionList().stream().map(questionVo -> {
            ExamQuestion examQuestion = new ExamQuestion();
            examQuestion.setExamId(exam.getExamId());
            examQuestion.setScore(questionVo.getScore());
            examQuestion.setQuestionId(questionVo.getQuestionId());
            return examQuestion;
        }).toList();
        boolean save1 = examQuestionService.saveBatch(list);
        if (!save1) {
            return AjaxJson.getError("保存失败");
        } else {
            return AjaxJson.getSuccess("保存成功");
        }
    }

    @Override
    public AjaxJson saveByExamAddVo(examAddVo examAddVo) {
        return saveExam(examAddVo);
    }
}
